package tij4.concurrent.exercise.ex30;

/*
    修改PipedIO使用BlockingQueue而不是使用管道
 */

import java.util.concurrent.*;

class IOBlockingQueue extends LinkedBlockingQueue<String> {
    //多此一举
}

class Sender implements Runnable {
    private IOBlockingQueue ioBlockingQueue;

    public Sender(IOBlockingQueue ioBlockingQueue) {
        this.ioBlockingQueue = ioBlockingQueue;
    }

    private String msg = new String();

    public String getMsg() {
        return msg;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                for (char c='A'; c<='z'; c++) {
                    msg = c+"";
                    ioBlockingQueue.put(msg);
                    TimeUnit.MILLISECONDS.sleep(500);
                }
            }
        }catch (InterruptedException e) {
            System.out.println(e + " sender interrupted");
        }
    }
}

class Reveiver implements Runnable {
    private IOBlockingQueue ioBlockingQueue;

    public Reveiver(IOBlockingQueue blockingQueue) {
        this.ioBlockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                String msg = ioBlockingQueue.take();
                System.out.println("Receiver: " + msg);
            }
        }catch (InterruptedException e) {
            System.out.println(e + " Reveiver inrterrupted");
        }
    }
}
public class BlockingQueueIO {
    public static void main(String[] args) throws Exception{
        IOBlockingQueue ioBlockingQueue = new IOBlockingQueue();
        Sender sender = new Sender(ioBlockingQueue);
        Reveiver reveiver = new Reveiver(ioBlockingQueue);
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(sender);
        executorService.execute(reveiver);
        TimeUnit.MILLISECONDS.sleep(5000);
        executorService.shutdownNow();
    }
}
